import React from 'react';
import PropTypes from 'prop-types';
import { Dialog, Form, Input, Field, Message } from '@teamix/ui';
import exceed from 'utils/apimap';
import AccessSelect from '../accessSelect';
import { checkGroupNamePath } from 'api/index.js';
import { navigate, navigateHref } from 'utils/router';
import AddonBeforeInput from 'components/addonBeforeInput';
import debounce from 'lodash.debounce';
import track from 'utils/track';
import utils from 'utils';
import { YunxiaoIcon } from '@alife/devops-ui';
import './index.scss';
import intl from '../../locale';

const FormItem = Form.Item;
const formItemLayout = {
  labelCol: {
    span: 6,
  },

  wrapperCol: {
    span: 14,
  },
};

const { organization } = window.FORCE;

export default class GroupModal extends React.Component {
  static propTypes = {
    trigger: PropTypes.element,
    successFn: PropTypes.func,
    closeModal: PropTypes.func,
    // 是否是新建子代码组标识 是：新建子代码组 否：建顶级组
    isSubgroup: PropTypes.bool,
    groupAccess: PropTypes.string,
    // 从新建代码库来新建组不需要跳转到组详情页
    isFromProjectModal: PropTypes.bool,
  };

  static defaultProps = {
    trigger: null,
    successFn: () => {},
    closeModal: () => {},
    isSubgroup: false,
    groupAccess: '',
    isFromProjectModal: false,
  };

  constructor(props) {
    super(props);
    this.field = new Field(this, {
      onChange: (name, value) => {
        if (name === 'name') {
          this.field.setValue('path', value || '');
          this.field.validate();
        }
      },
    });

    this.state = {
      // formItemData: [],
      submitting: false,
      isModalOpen: false,
    };

    this.pathValidator = debounce(this.pathValidator, 500);
    // this.nameValidator = debounce(this.nameValidator, 500);
  }

  static getDerivedStateFromProps(props) {
    if (props.trigger) {
      return {};
    }
    return {
      isModalOpen: props.isModalOpen,
    };
  }

  showModal = () => {
    this.setState({
      isModalOpen: true,
    });
  };

  pathValidator = (rule, value, callback) => {
    this.commonValidator(false, value, callback);
  };

  nameValidator = (rule, value, callback) => {
    this.commonValidator(true, value, callback);
  };

  commonValidator = (isName, value, callback) => {
    const { pathResource } = window.FORCE;
    if (!value || /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,}$/.test(value)) {
      checkGroupNamePath({
        name: `${isName ? value : ''}`,
        path: `${isName ? '' : value}`,
        namespace_id: this.props.isSubgroup ? pathResource.id : organization.namespace_id,
      })
        .then(() => {
          callback();
        })
        .catch((err) => {
          if (err.responseText) {
            const errCause = JSON.parse(err.responseText).cause;
            callback(`${errCause}`);
          } else {
            throw err;
          }
        });
    } else {
      callback(
        intl.get({
          id: 'code-assets.src.utils.locale.ItCanOnlyContainLetters',
          defaultMessage: "只能包含字母和数字、 '_'、 '.'和'-'，且只能以字母、数字或'_'开头",
        }),
      );
    }
  };

  lengthValidator = (rule, value, callback) => {
    if (!value) {
      callback();
      return;
    }
    const pathAddonTextBefore = this.getAddonBeforeText();
    const curPath = pathAddonTextBefore + value;

    if (curPath.length > 255) {
      callback(
        intl.get(
          {
            id: 'code-assets.components.createGroupModal.ThePathIsInvalidThe',
            defaultMessage: '路径不合法，路径总长度须小于 256 字符，当前共 {curPathLength} 字符',
          },
          { curPathLength: curPath.length },
        ),
      );
      return;
    }
    callback();
  };

  onClose = (result) => {
    this.setState({
      isModalOpen: false,
    });

    this.resetUrlParams();
    this.props.closeModal(result);
  };

  // 从devops跳转到codeup新建组需要将参数去除，否则弹窗一直在或者浏览器后退也会在
  resetUrlParams = () => {
    const showCreateGroupModal = utils.getUrlSearchParam('showCreateGroupModal') || '';
    if (showCreateGroupModal) {
      window.history.replaceState({}, null, '/groups?navKey=mine');
    }
  };

  handleOk = () => {
    this.field.validate((errors) => {
      if (!errors) {
        if (this.state.submitting) {
          return;
        }
        this.setState({ submitting: true });
        const formData = this.field.getValues();
        this.formSubmit(formData, (result) => {
          this.setState({ submitting: false });
          this.onClose(result);
        });
      }
    });
  };

  // 创建子组
  formSubmit = (formData, cb) => {
    const { pathResource } = window.FORCE;
    exceed
      .fetch({
        api: 'groups.post',
        data: {
          ...formData,
          parent_id: this.props.isSubgroup
            ? Number(pathResource.id)
            : Number(organization.namespace_id),
        },
      })
      .then((result) => {
        Message.success({
          title: intl.get({
            id: 'code-assets.components.createGroupModal.TheCodeGroupIsCreated',
            defaultMessage: '代码组新建成功',
          }),
        });

        track({
          action: 'complete_new_group',
          page: '',
          type: this.props.isSubgroup ? 'subgroup' : 'group',
          control: '',
        });

        if (this.props.isFromProjectModal) {
          cb && cb(result);
          return;
        }
        this.resetUrlParams();

        const href = `/${result.path_with_namespace}`;
        // 错误页面直接跳转
        const isErrorPage = window.ERROR && window.ERROR.errorCode;
        if (isErrorPage) {
          navigateHref(href);
        } else {
          navigate(href, { state: { forceUpdate: true } });
        }
        cb && cb(result);
      })
      .fail(() => {
        // 接口报错也要回调，以让按钮取消loading状态
        cb && cb('isFail');
      });
  };

  handleChangeAccess = (value) => {
    this.field.setValue('visibility_level', value);
  };

  setVisibilityLevel = (value) => {
    this.field.setValue('visibility_level', value);
    // 全部禁用时需要提醒 存在私有-0
    if (value === '' || value === undefined) {
      this.field.setError(
        'visibility_level',
        intl.get({
          id: 'code-assets.src.utils.locale.ThisParameterIsRequired',
          defaultMessage: '该项为必填项',
        }),
      );
    } else {
      this.field.setError('visibility_level', '');
    }
  };

  getAddonBeforeText = () => {
    const { isSubgroup } = this.props;
    const { pathResource } = window.FORCE;
    const pathAddonTextBefore = isSubgroup
      ? `${window.location.origin}/${pathResource.fullPath}/`
      : `${window.location.origin}/${organization.path}/`;
    return pathAddonTextBefore;
  };

  render() {
    const { init } = this.field;
    const { isSubgroup, groupAccess } = this.props;
    const dialogDisabled =
      (this.field.getValue('name') === undefined && this.field.getValue('path') === undefined) ||
      this.field.getError('name') !== null ||
      this.field.getError('path') !== null;

    const pathAddonTextBefore = this.getAddonBeforeText();
    const pathValue = this.field.getValue('path');

    return (
      <React.Fragment>
        {this.state.isModalOpen ? (
          <Dialog
            title={
              isSubgroup
                ? intl.get({
                    id: 'code-assets.src.utils.locale.CreateASubcodeGroup',
                    defaultMessage: '新建子代码组',
                  })
                : intl.get({
                    id: 'code-assets.src.utils.locale.CreateACodeGroup',
                    defaultMessage: '新建代码组',
                  })
            }
            visible
            style={{ width: '692px' }}
            onOk={this.handleOk}
            onCancel={this.onClose}
            onClose={this.onClose}
            okProps={{
              dialogDisabled,
              loading: !!this.state.submitting,
            }}
          >
            <Form {...formItemLayout} field={this.field} labelAlign="top">
              <FormItem
                label={
                  isSubgroup
                    ? intl.get({
                        id: 'code-assets.components.createGroupModal.SubcodeGroupName',
                        defaultMessage: '子代码组名称',
                      })
                    : intl.get({
                        id: 'code-assets.components.createGroupModal.CodeGroupName',
                        defaultMessage: '代码组名称',
                      })
                }
                required
              >
                <Input
                  autoFocus
                  spellCheck={false}
                  maxLength={100}
                  hasLimitHint
                  placeholder={
                    isSubgroup
                      ? intl.get({
                          id: 'code-assets.components.createGroupModal.EnterASubcodeGroupName',
                          defaultMessage: '请输入子代码组名称',
                        })
                      : intl.get({
                          id: 'code-assets.components.createGroupModal.EnterACodeGroupName',
                          defaultMessage: '请输入代码组名称',
                        })
                  }
                  {...init('name', {
                    rules: [
                      {
                        required: true,
                        message: intl.get({
                          id: 'code-assets.src.utils.locale.ThisParameterIsRequired',
                          defaultMessage: '该项为必填项',
                        }),
                      },

                      {
                        validator: this.nameValidator,
                      },
                    ],
                  })}
                />
              </FormItem>
              <FormItem
                label={
                  isSubgroup
                    ? intl.get({
                        id: 'code-assets.components.createGroupModal.SubcodeGroupPath',
                        defaultMessage: '子代码组路径',
                      })
                    : intl.get({
                        id: 'code-assets.components.createGroupModal.CodeGroupPath',
                        defaultMessage: '代码组路径',
                      })
                }
                required
              >
                <AddonBeforeInput
                  addonTextBefore={pathAddonTextBefore}
                  placeholder={
                    isSubgroup
                      ? intl.get({
                          id: 'code-assets.components.createGroupModal.EnterASubcodeGroupPath',
                          defaultMessage: '请输入子代码组路径，建议限制在 30 字符以内',
                        })
                      : intl.get({
                          id: 'code-assets.components.createGroupModal.EnterTheCodeGroupPath',
                          defaultMessage: '请输入代码组路径，建议限制在 30 字符以内',
                        })
                  }
                  style={{ width: '100%' }}
                  spellCheck={false}
                  {...init('path', {
                    rules: [
                      {
                        required: true,
                        message: intl.get({
                          id: 'code-assets.src.utils.locale.ThisParameterIsRequired',
                          defaultMessage: '该项为必填项',
                        }),
                      },
                      {
                        validator: this.lengthValidator,
                      },

                      {
                        validator: this.pathValidator,
                      },
                    ],
                  })}
                />

                {
                  // (30, 255] 显示警告
                  pathValue &&
                    pathValue.length > 30 &&
                    pathValue.length + pathAddonTextBefore.length <= 255 && (
                      <div className="next-form-item-help group-path-warning-help">
                        <YunxiaoIcon type="warning-fill" />
                        <span className="next-form-item-help-text">
                          {intl.get({
                            id: 'code-assets.components.createGroupModal.WeRecommendThatYouSet',
                            defaultMessage:
                              '建议控制 30 字符以内，路径总长度须小于 256 字符，当前组路径过长可能导致无法创建子代码组',
                          })}
                        </span>
                      </div>
                    )
                }
              </FormItem>
              <FormItem
                label={intl.get({
                  id: 'code-assets.src.utils.locale.Description.2',
                  defaultMessage: '代码组描述',
                })}
                validator={this.checkPass2}
              >
                <Input.TextArea
                  placeholder={intl.get({
                    id: 'code-assets.src.utils.locale.EnterADescription',
                    defaultMessage: '请输入描述',
                  })}
                  {...init('description')}
                />
              </FormItem>
              <FormItem
                required
                label={
                  <span>
                    {intl.get({
                      id: 'code-assets.src.utils.locale.Openness',
                      defaultMessage: '公开性',
                    })}
                  </span>
                }
              >
                <AccessSelect
                  placeholder={intl.get({
                    id: 'code-assets.src.utils.locale.SelectPublicity',
                    defaultMessage: '请选择公开性',
                  })}
                  {...init('visibility_level', {
                    rules: [
                      {
                        required: true,
                        message: intl.get({
                          id: 'code-assets.src.utils.locale.ThisParameterIsRequired',
                          defaultMessage: '该项为必填项',
                        }),
                      },
                    ],
                  })}
                  onChange={this.handleChangeAccess}
                  style={{ width: '324px' }}
                  isRepo={false}
                  groupAccess={groupAccess}
                  initValueFn={this.setVisibilityLevel}
                />
              </FormItem>
            </Form>
          </Dialog>
        ) : null}
        {!!this.props.trigger &&
          React.cloneElement(this.props.trigger, { onClick: this.showModal })}
      </React.Fragment>
    );
  }
}
